package cn.itcast.goods.book.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import cn.itcast.goods.book.domain.Book;
import cn.itcast.goods.pager.Expression;
import cn.itcast.goods.pager.PageBean;
import cn.itcast.goods.pager.PageConstant;
import cn.itcast.jdbc.TxQueryRunner;

public class BookDao {
	QueryRunner qr=new TxQueryRunner();
	
	/**
	 * 多条件组合查询
	 * @param criteria
	 * @param pc
	 * @return
	 * @throws SQLException
	 */
	public PageBean<Book> findByCombination(Book criteria, int pc) throws SQLException{
		List<Expression> expList=new ArrayList<Expression>();
		expList.add(new Expression("bname","like","%"+criteria.getBname()+"%"));
		expList.add(new Expression("author","like","%"+criteria.getAuthor()+"%"));
		expList.add(new Expression("press","like","%"+criteria.getPress()+"%"));
		return findByCriteria(expList, pc);
	}
	/**
	 * 按照出版社查
	 * @param press
	 * @param pc
	 * @return
	 * @throws SQLException
	 */
	public PageBean<Book> findByPress(String press, int pc) throws SQLException{
		List<Expression> expList=new ArrayList<Expression>();
		expList.add(new Expression("press","like","%"+press+"%"));
		return findByCriteria(expList, pc);
	}
	/**
	 * 按照作者查
	 * @param author
	 * @param pc
	 * @return
	 * @throws SQLException
	 */
	public PageBean<Book> findByAuthor(String author, int pc) throws SQLException{
		List<Expression> expList=new ArrayList<Expression>();
		expList.add(new Expression("author","like","%"+author+"%"));
		return findByCriteria(expList, pc);
	}
	/**
	 * 按分类查询
	 * @param cid
	 * @param pc
	 * @return
	 * @throws SQLException 
	 */
	public PageBean<Book> findByCategory(String cid, int pc) throws SQLException{
		List<Expression> expList=new ArrayList<Expression>();
		expList.add(new Expression("cid","=",""+pc));
		return findByCriteria(expList, pc);
	}
	
	/**
	 * 按照书名进行模糊查询
	 * @param bname
	 * @param pc
	 * @return
	 * @throws SQLException
	 */
	public PageBean<Book> findByBname(String bname, int pc) throws SQLException{
		List<Expression> expList=new ArrayList<Expression>();
		expList.add(new Expression("bname","like","%"+bname+"%"));
		return findByCriteria(expList, pc);
	}
	/**
	 * 通用的查询方法
	 * @param expList 指定查询语句的where子句的查询参数
	 * @param pc 指定要显示哪一页
	 * @return 存储某一页查询的结果
	 * @throws SQLException
	 */
	private PageBean<Book> findByCriteria(List<Expression> expList, int pc) throws SQLException{
		/**
		 * 1.得到ps
		 * 2.得到tr
		 * 3.得到beanList
		 * 4.创建PageBean,返回
		 */
		/**
		 * 1.得到ps
		 */
		int ps=PageConstant.BOOK_PAGE_SIZE;//创建了一个PageConstant对象，里面由一个静态常量，存储每页的大小
		/**
		 * 2.通过expList来生成where子句
		 */
		//where子句中，为使格式统一，可预置条件1=1，这样以后每次添加条件的时候只需要添加and + 条件 即可
		StringBuilder whereSQL=new StringBuilder(" where 1=1");
		List<Object> params=new ArrayList<Object>();//存储SQL中的？所对应的数值
		//提取expList中的数据
		for (Expression exp : expList) {
			whereSQL.append(" and ").append(exp.getName())
			.append(" ").append(exp.getOperator()).append(" ");
			//只有is null 后面没有数值，若有值，提取出来存储到params中，共数据库查询工具使用
			if(!exp.getOperator().equals("is null")){
				whereSQL.append("?");
				params.add(exp.getValue());
			}
		}
		/**
		 * 3.获得总记录数
		 */
		String sql="select count(*) from t_book"+whereSQL;
		Number number=(Number) qr.query(sql, new ScalarHandler(), params.toArray());
		int tr=number.intValue();
		/**
		 * 4.得到beanList，即当前页记录。注意MySQL数据库特有的功能，可以输出指定游标的记录，使用limit进行限制。
		 * 第一个问号是其起始位置，第二个是选取的记录数目
		 */
		sql="select * from t_book"+whereSQL+"order by orderBy limit ?，？";
		/**
		 * 注意：之前params中已经存储了whereSQL语句需要的参数，此处进行添加后面limit语句中的参数
		 */
		params.add((pc-1)*ps);//当前页首行的下标，注意下标从0开始
		params.add(ps);//每页显示的记录数
		List<Book> bookList=qr.query(sql, new BeanListHandler<Book>(Book.class),params.toArray());
		/**
		 * 5.创建PageBean，并设置相应的参数，其中url由servlet进行设置
		 */
		PageBean<Book> pb=new PageBean<Book>();
		pb.setBeanList(bookList);
		pb.setPc(pc);
		pb.setPs(ps);
		pb.setTr(tr);
		 
		return pb;
	}
}
